package com.lohika  
{
	import com.lohika.util.GameUtil;
	
	import events.EntityEvent;
	import events.GameEvent;
	
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;
	import flash.media.Sound;
	import flash.utils.setTimeout;
	
	

	/**
	 * JUST UI (VIEW) 
	 * Here we just analise mouse clicking on items
	 * 
	 * @author Vitaly Vrublevskyy
	 */
	public class Board extends ChessBoardContainer 
	{
		private var container:Sprite;
		
		private var firstSelected:Entity;
		private var grid:Grid;
		
		private var mouseSensative:Boolean; // block mouse when running effects
			
		public function Board(grid:Grid) 
		{
			super();
			
			this.grid = grid;
			
			addEventListener(EntityEvent.SELECT, onEntitySelect); //just one listener for all items
			mouseSensative = true;
			
			container = new Sprite();
			addChild(container);
		}
		
		public function initialize():void
		{
			for each (var columns:Array in grid.source) 
				for each (var entity:Entity in columns) 
					add(entity);
		}
		
		public function add(entity:Entity):void
		{
			container.addChild(entity.container);
		}
		
		public function remove(entity:Entity):void
		{
			container.removeChild(entity.container);
			entity.container = null;
		}
		
		public function show():void
		{
			container.visible = true;
		}
		
		public function hide():void
		{
			container.visible = false;
		}
		
		public function mute():void
		{
			container.alpha = 0.5;
		}
		
		private function buildItems(source:Array):void 
		{
			for (var i:int = 0; i < source.length; i++) 
			{
				for (var j:int = 0; j < source[i].length; j++) 
				{
					var entity:Entity = source[i][j] as Entity;
					add(entity);
				}
			}
		}
	
		
		private function onEntitySelect(e:EntityEvent):void 
		{
			e.stopPropagation();

			var sound:Sound = mouseSensative ? new SoundClick() : new SoundDisabledClick()
			GameUtil.playSound( sound );
			
			if (mouseSensative)
			{
				var entity:Entity = e.first as Entity;
				analiseClick( entity);
			}
		}
		
		private function analiseClick(entity:Entity):void
		{
			if (firstSelected == null)
			{
				firstSelected = entity;
				firstSelected.select();
			} 
			else if (firstSelected == entity)
			{
				firstSelected.deselect();
				firstSelected = null; //reset
			}
			else
			{
				firstSelected.deselect();
				
				if ( firstSelected.isNeighbour(entity) )
				{
					replaceItems(firstSelected, entity);
					firstSelected = null;
				}
				else
				{
					firstSelected = entity;
					firstSelected.select();
				}
			}

		}
		
		private function replaceItems(first:Entity, second:Entity):void 
		{
			this.addEventListener(EntityEvent.REPLACED, onReplaceFinished);
			swapEntity(first, second);
		}
		
		protected function onReplaceFinished(event:EntityEvent):void
		{
			event.stopPropagation();
			removeEventListener(EntityEvent.REPLACED, onReplaceFinished);
			
			var first:Entity = event.first; 
			var second:Entity = event.second; 
			
			if ( grid.existMatchesLines() ) 
			{
				mouseSensative = false;
				grid.removeMatchedLines();
				grid.addEventListener(GameEvent.REMOVED_ALL_LINES, onRemovedAllLines);
			}
			else
			{   //roll back
				swapEntity(first, second); 
			}
		}
		
		protected function onRemovedAllLines(event:Event):void
		{
			(event.target as Grid).removeEventListener(GameEvent.REMOVED_ALL_LINES, onRemovedAllLines)
			mouseSensative = true;
		}
		
		private function swapEntity(first:Entity, second:Entity):void 
		{
			
			first.swap(second);
			
			//update model
			grid.source[first.column][first.row] = first;
			grid.source[second.column][second.row] = second;
		}
		
	}

}